package com.lkd.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.lkd.config.TopicConfig;
import com.lkd.contract.SupplyChannel;
import com.lkd.contract.SupplyContract;
import com.lkd.dao.ChannelDao;
import com.lkd.emq.MqttProducer;
import com.lkd.entity.ChannelEntity;
import com.lkd.entity.SkuEntity;
import com.lkd.exception.LogicException;
import com.lkd.http.vo.VMChannelConfig;
import com.lkd.service.ChannelService;
import com.lkd.service.SkuService;
import com.lkd.utils.JsonUtil;
import com.lkd.vo.Pager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class ChannelServiceImpl extends ServiceImpl<ChannelDao, ChannelEntity> implements ChannelService {

    @Autowired
    private SkuService skuService;
    @Autowired
    private MqttProducer mqttProducer;

    @Override
    public Pager<ChannelEntity> findPage(long pageIndex, long pageSize, Map searchMap) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<ChannelEntity> page =
                new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(pageIndex, pageSize);

        QueryWrapper queryWrapper = createQueryWrapper(searchMap);
        this.page(page, queryWrapper);

        Pager<ChannelEntity> pageResult = new Pager<>();
        pageResult.setCurrentPageRecords(page.getRecords());
        pageResult.setPageIndex(page.getCurrent());
        pageResult.setPageSize(page.getSize());
        pageResult.setTotalCount(page.getTotal());
        return pageResult;
    }

    @Override
    public List<ChannelEntity> getChannelesByInnerCode(String innerCode) {
        LambdaQueryWrapper<ChannelEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChannelEntity::getInnerCode, innerCode);

        return this.list(queryWrapper);
    }

    @Override
    public ChannelEntity getChannelInfo(String innerCode, String channelCode) {
        LambdaQueryWrapper<ChannelEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper
                .eq(ChannelEntity::getInnerCode, innerCode)
                .eq(ChannelEntity::getChannelCode, channelCode);
        return this.getOne(queryWrapper);
    }

    @Override
    public List<ChannelEntity> findList(Map searchMap) {
        QueryWrapper queryWrapper = createQueryWrapper(searchMap);

        return this.list(queryWrapper);
    }

    /**
     * 条件构建
     *
     * @param searchMap
     * @return
     */
    private QueryWrapper createQueryWrapper(Map searchMap) {
        QueryWrapper queryWrapper = new QueryWrapper();
        if (searchMap != null) {
            queryWrapper.allEq(searchMap);
        }
        return queryWrapper;
    }


    /**
     * 设置商品
     *
     * @param innerCode
     * @param channelCode
     * @param skuId
     * @return
     */
    private boolean configSku(String innerCode, String channelCode, long skuId) {

        if (skuId <= 0) {
            return false;
        }
        SkuEntity skuEntity = skuService.getById(skuId); //查询商品
        if (skuEntity == null) {
            return false;
        }

        ChannelEntity channel = this.getChannelInfo(innerCode, channelCode);
        if (channel == null) {
            throw new LogicException("该货道不存在");
        }
        channel.setSkuId(skuId);
        channel.setPrice(skuEntity.getPrice());
        return this.updateById(channel);
    }


    @Override
    @Transactional(rollbackFor = {Exception.class})
    public Boolean mapSku(VMChannelConfig channelConfig) {
        channelConfig.getChannelList().forEach(c ->
                configSku(channelConfig.getInnerCode(), c.getChannelCode(), Long.valueOf(c.getSkuId())));
        return true;
    }

    /**
     * 获取缺货货道数据发送EMQ
     *
     * @param innerCode
     * @return
     */
    @Override
    public void StockChannelsEMQ(String innerCode) {
        //获取售货机货道信息
        List<ChannelEntity> entityList = getChannelesByInnerCode(innerCode);
        //封装协议类信息
        SupplyContract supplyContract = new SupplyContract();
        supplyContract.setInnerCode(innerCode);
        //协议类货道信息
        List<SupplyChannel> supplyData = new ArrayList<>();
        //遍历获取的货道信息查找相同活动编号的信息
        List<SupplyChannel> supplyChannels = getsupplyData(innerCode, entityList, supplyData);
        supplyContract.setSupplyData(supplyChannels);
        //发送EMQ
        try {
            mqttProducer.send(TopicConfig.TASK_SUPPLY_TOPIC, JsonUtil.serialize(supplyContract));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            throw new LogicException("发送主题失败");
        }
    }

    /**
     * 遍历获取的货道信息查找相同活动编号的信息
     *
     * @param innerCode
     * @param entityList
     * @param supplyData
     * @return
     */
    private List<SupplyChannel> getsupplyData(String innerCode, List<ChannelEntity> entityList, List<SupplyChannel> supplyData) {
        for (ChannelEntity channelEntity : entityList) {
            for (SupplyChannel supplyChannel : supplyData) {
                //单条货道信息
                ChannelEntity channelInfo = getChannelInfo(innerCode, channelEntity.getChannelCode());
                supplyChannel.setChannelId(channelInfo.getChannelCode());
                supplyChannel.setSkuId(channelInfo.getSkuId());
                //判断货道容量是否需要补充
                if (channelEntity.getCurrentCapacity() < channelEntity.getMaxCapacity()) {
                    supplyChannel.setCapacity(channelEntity.getMaxCapacity() - channelEntity.getCurrentCapacity());
                }
                if (channelEntity.getCurrentCapacity() == channelEntity.getMaxCapacity()) {
                    supplyChannel.setCapacity(channelEntity.getCurrentCapacity());
                }
                //设置商品信息
                LambdaQueryWrapper<SkuEntity> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(SkuEntity::getSkuId, channelEntity.getSkuId());
                SkuEntity sku = skuService.getOne(wrapper);
                supplyChannel.setSkuName(sku.getSkuName());
                supplyChannel.setSkuImage(sku.getSkuImage());
            }
        }
        return supplyData;
    }
}
